Проект: якорение DID и VC в HLF (R4)

Черновик для обсуждения с Димой и Ромой. Срез кода: develop 8d4f3df5a + ветка feature/todo-261015-2253-did-signed-ops (2026-10-15). Не реализовано — нужно решение команды.

Что уже есть после ветки

  • Каждая ревизия DID хранит подпись операции, подписанное тело и digest/prevDigest (хэш-цепочка).

  • GET /v1/dids/{did}/history/verify пересчитывает цепочку и подписи, отдаёт headDigest.

  • Внутри сервиса не ловятся: подмена неподписанных ревизий целиком и обрезка хвоста истории. Это и закрывает якорение: в реестре лежит digest каждой ревизии, сервис сверяется с ним.

Где HLF сейчас (по коду монорепы)

  • Доступ к сети — через blockchain-svc (gRPC InvokeSmartContract / QuerySmartContract, инициализация CreateClient → SetClientPeers → SetClientChaincodes → SetClientConfig → CreateWallet → SetWalletConfig), образец — poa-svc/internal/service/blockchain.go, повтор — [[KCONT-2248]] (documents-svc).

  • docs-chaincode-svc хранит документы в private data collections (NewPrivateDocsRepository, GetPrivateDataHash). Это и есть SideDB из заметок команды: данные видят только члены коллекции, в world state лежит лишь хэш. Для DID/VC как публичного реестра это не подходит — DID должен резолвиться любым участником канала, статус VC — проверяться любым верификатором.

Предложение

Отдельный чейнкод did-registry, world state

Ключ (composite)

Значение

Кто пишет

did~<did>~<versionId>

{digest, prevDigest, operation, signerDid, keyId, recordedAt}

did-svc после записи ревизии

didhead~<did>

{versionId, digest, deactivated}

тот же вызов

vcstatus~<credentialId>

{digest, issuer, status, statusAt}

vc-svc при выпуске/отзыве

Правила в чейнкоде (а не только в сервисе):

  1. prevDigest новой записи == digest текущей головы (иначе отказ) — обрезка/подмена истории невозможна без следа в реестре.

  2. Для подписанных операций чейнкод проверяет JWS операции (EdDSA/ECDSA — stdlib Go в чейнкоде) по ключу подписанта, взятому из своей же записи DID подписанта. Тогда доверие к did-svc не нужно: чейнкод — независимый проверяющий. Требует хранить в world state и публичные ключи (didkeys~<did>~<versionId>), без персональных данных — только JWK.

  3. Деактивированный DID (didhead.deactivated) — запись новых версий запрещена.

Содержимое документов в реестр не кладём: только отпечатки и ключи. DID Document персоны (did:i:fl:*) содержит service endpoint на identity-сервис — ПДн там нет, но и класть незачем.

Как did-svc пишет: outbox, а не синхронный вызов

  • В той же транзакции, что и ревизия, — строка в did_anchor_outbox (did, version, payload, attempts, anchored_at, last_error).

  • Воркер забирает неотправленные, вызывает InvokeSmartContract, отмечает anchored_at.

  • Недоступный HLF не роняет приём операций (как решено для documents-svc в KCONT-2248), но history/verify показывает для ревизии anchored: false.

  • Режим строгости — по аналогии с DID_OPERATION_PROOF: DID_ANCHOR=off|async|required (required — операция подтверждается клиенту только после записи в реестр).

Проверка

history/verify дополнительно читает did~<did>~* из реестра (QuerySmartContract) и сверяет digest каждой ревизии: расхождение → broken, отсутствие → unanchored.

Вопросы к команде

  1. Один чейнкод на DID и статусы VC или два? (Предлагаю один did-registry — проще эндорсмент.)

  2. Канал: org (как docs-chaincode) или отдельный? Политика эндорсмента?

  3. Проверять JWS операций в чейнкоде (п. 2) или доверять did-svc? С ГОСТ-подписями в чейнкоде понадобится КриптоПро/cryptosmart на пирах — это аргумент проверять только EdDSA/ECDSA, а ГОСТ (L3, УКЭП) оставить проверке PKI-сервиса.

  4. Identity did-svc в сети: Admin организации (как временно в KCONT-2248) или отдельный через Fabric CA.

  5. bcprovider: cryptosmart-proxy по умолчанию в blockchain-svc (риск из KCONT-2248) — для did-registry на тестовой сети нужен vanilla.

Объём (оценка)

  • чейнкод did-registry (3 функции записи, 2 чтения, проверки 1 и 3; п. 2 — +1 день) — 2–3 дня;

  • outbox + воркер + клиент blockchain-svc в did-svc (по образцу poa-svc/KCONT-2248) — 2 дня;

  • сверка в history/verify, тесты, деплой в тестовую сеть ([[KCONT-2244]]) — 1–2 дня.

Журнал изменений

Дата

Перечень изменений

Автор

2026-11-05

Перенесён из архива DID-VC-итоги-2026-11-03 без изменения содержания.

Дис